package cn.myeasyai;

import cn.myeasyai.face.*;
import cn.myeasyai.util.SourceUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import cn.myeasyai.temple.AllTemple;
import cn.myeasyai.temple.TestBody;
import org.dromara.easyai.entity.ThreeChannelMatrix;
import org.dromara.easyai.matrixTools.Matrix;
import org.dromara.easyai.matrixTools.MatrixOperation;
import org.dromara.easyai.tools.ImageTools;
import org.dromara.easyai.tools.Picture;

import java.io.*;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;

/**
 * Hello world!
 */
public class App {
    private static Face face;

    public static void main(String[] args) throws Exception {
        init();
       // test("/Users/lidapeng/job/faceData/myFaceTest");
        //test2();
        test3();
    }

    public static void test3() throws Exception {
        MatrixOperation matrixOperation = new MatrixOperation();
        ThreeChannelMatrix m1 = Picture.getThreeMatrix("/Users/lidapeng/job/faceData/a4.jpg",true);//062896
        ThreeChannelMatrix m2 = Picture.getThreeMatrix("/Users/lidapeng/job/faceData/d1.jpg",true);
        FaceMessage faceMessage1 = face.look(m1, 1, 25).getFaceMessage();
        FaceMessage faceMessage2 = face.look(m2, 2, 25).getFaceMessage();
        double a = matrixOperation.getEDistByMatrix(faceMessage1.getFeature(), faceMessage2.getFeature());
        System.out.println(a);
        ImageTools.writeImage(faceMessage1.getChannel(), "/Users/lidapeng/job/faceData/test/b1.jpg");
        ImageTools.writeImage(faceMessage2.getChannel(), "/Users/lidapeng/job/faceData/test/b2.jpg");

    }

    public static void test2() throws Exception {//width:1280,height:1707
        ThreeChannelMatrix m = Picture.getThreeMatrix("/Users/lidapeng/job/faceData/m8.jpg",true);
        ImageTools imageTools = new ImageTools();
        ImageTools.writeImage(m, "/Users/lidapeng/job/faceData/test/dd.jpg");
        FaceMessage faceMessage = face.look(m, 1, 30).getFaceMessage();
        if (faceMessage != null) {
            System.out.println(faceMessage.getDist());
            ThreeChannelMatrix threeChannelMatrix = faceMessage.getChannel();
            ImageTools.writeImage(threeChannelMatrix, "/Users/lidapeng/job/faceData/test/cc.jpg");
        } else {
            System.out.println("质量太差");
        }

    }


    public static ErrorMessage look(File file, long eventID, String url) throws Exception {
        ThreeChannelMatrix pic;
        if (url == null) {
            pic = Picture.getThreeMatrix(file, true);
        } else {
            pic = Picture.getThreeMatrix(url,true);
        }
        FaceTestConfig faceTestConfig = new FaceTestConfig();
        return face.look(pic, eventID, faceTestConfig.getSecondExplore());
    }

    public static void test(String templeUrl) throws Exception {
        MatrixOperation operation = new MatrixOperation();
        File folder = new File(templeUrl);
        File[] files = folder.listFiles();
        FaceMessage faceMessage1 = look(null, 1, "/Users/lidapeng/job/faceData/a3.jpg").getFaceMessage();
        Matrix myMatrix = faceMessage1.getFeature();
        List<TestBody> testBodies = new ArrayList<>();
        TestBody testBody1 = new TestBody();
        FaceMessage faceMessage2 = look(null, 2, "/Users/lidapeng/job/faceData/a7.jpg").getFaceMessage();
        Matrix otherMatrix = faceMessage2.getFeature();
        ImageTools.writeImage(faceMessage1.getChannel(), "/Users/lidapeng/job/faceData/test/b1.jpg");
        ImageTools.writeImage(faceMessage2.getChannel(), "/Users/lidapeng/job/faceData/test/b2.jpg");
        testBody1.setMatrix(otherMatrix);
        testBody1.setFileName("命中目标文件");
        testBodies.add(testBody1);
        double dd = operation.getEDistByMatrix(myMatrix, otherMatrix);//9154
        int index = 1;
        double maxNorm = 0;
        for (File file : files) {
            TestBody testBody = new TestBody();
            String fileName = file.getName();
            if (!fileName.contains(".DS")) {
                System.out.println(fileName);
                ErrorMessage errorMessage = look(file, index, null);
                if (errorMessage.getErrorCode() == 0) {
                    FaceMessage faceMessage = errorMessage.getFaceMessage();
                    if (faceMessage.getDist() > maxNorm) {
                        maxNorm = faceMessage.getDist();
                    }
                    Matrix feature = faceMessage.getFeature();
                    testBody.setFileName(fileName);
                    testBody.setMatrix(feature);
                    testBodies.add(testBody);
                    index++;
                    if (index == 100) {
                        break;
                    }
                }
            }
        }
        String url = "";
        double minDist = -1;
        for (TestBody testBody : testBodies) {
            double dist = operation.getEDistByMatrix(myMatrix, testBody.getMatrix());
            if (minDist < 0 || dist < minDist) {
                minDist = dist;
                url = testBody.getFileName();
            }
        }
        System.out.println("最相近的人脸===" + url + ",dist==" + minDist + ",dd:" + dd + ",minNorm==" + maxNorm);
    }

    public static void init() throws Exception {
        face = FaceFactory.getFace();
    }

    public static void study() throws Exception {
        ThreeChannelMatrix avgMatrix = Picture.getThreeMatrix("/Users/lidapeng/job/faceData/test/avgFace.png",true);
        List<AllTemple> allTemples = new ArrayList<>();
        AllTemple allTemple1 = new AllTemple();
        AllTemple allTemple2 = new AllTemple();
        allTemples.add(allTemple1);
        allTemples.add(allTemple2);
        allTemple1.setTempleUrl("/Users/lidapeng/job/faceData/biaozhu");
        allTemple1.setPictureUrl("/Users/lidapeng/job/faceData/success");
        allTemple2.setTempleUrl("/Users/lidapeng/job/faceData/biaozhu2");
        allTemple2.setPictureUrl("/Users/lidapeng/job/faceData/success2");
        Face face = new Face(new FaceTestConfig(), avgMatrix);
        face.insertModel(readCreatorModel2());
        face.facePositionStudy(allTemples);
        FaceModel faceModel = face.getModel();
        writeModel(JSON.toJSONString(faceModel), "/Users/lidapeng/job/faceData/model/face.json");//1
        //face.study(allTemples);
        //FaceModel faceModel = face.getModel();
        //writeModel(JSON.toJSONString(faceModel), "/Users/lidapeng/job/faceData/model/model5.json");//1
    }

    private static void writeModel(String model, String url) throws IOException {//写出模型与 激活参数
        OutputStreamWriter out = new OutputStreamWriter(Files.newOutputStream(Paths.get(url)), StandardCharsets.UTF_8);
        out.write(model);
        out.close();
    }

    private static FaceModel readCreatorModel2() {
        final File file = SourceUtil.getResourceFile("face.json");
        String a = readPaper(file);
        return JSONObject.parseObject(a, FaceModel.class);
    }

    private static FaceModel readCreatorModel(int i) {
        File file = new File("/Users/lidapeng/job/faceData/model/model" + i + ".json");
        String a = readPaper(file);
        return JSONObject.parseObject(a, FaceModel.class);
    }

    private static String readPaper(File file) {
        InputStream read = null;
        String context = null;
        try {
            read = Files.newInputStream(file.toPath());
            byte[] bt = new byte[read.available()];
            read.read(bt);
            context = new String(bt, StandardCharsets.UTF_8);
            read.close();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (read != null) {
                try {
                    read.close(); //确保关闭
                } catch (IOException el) {
                }
            }
        }
        return context;
    }
}